package com.mc.service.initialize;


import com.mc.common.annotation.ServiceMapping;
import com.mc.common.utils.BeanUtils;
import com.mc.common.utils.SpringContextUtils;
import com.mc.service.invoke.ApiServiceMapping;
import com.mc.service.invoke.ApiServiceMappingInfo;
import com.mc.service.invoke.ClassHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author zhangyu
 * @Description 用来初始化所有apiService
 * @date 2018/10/9 0009 下午 21:00
 */
@Component//被spring容器管理
@Order(1)//如果多个自定义ApplicationRunner，用来标明执行顺序
public class ServerApplicationRunner implements ApplicationRunner {

    @Autowired
    SpringContextUtils springContextUtils;
    private List<String> list = new ArrayList<>();

    public void initPackegData() {
        list.add("com.mc.service.service");
    }


    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {

        initPackegData();
        for (String packageName : list) {

            Set<Class<?>> setClasses = ClassHelper.getClasses(packageName);
            for (Class<?> clazz : setClasses) {
                Method[] methods = BeanUtils.findDeclaredMethods(clazz);
                for (Method m : methods) {
                    if (m.isAnnotationPresent(ServiceMapping.class)) {
                        String method = m.getAnnotation(ServiceMapping.class).value();
                        if (!StringUtils.isBlank(method)) {
                            if (ApiServiceMapping.requestMap.containsKey(method)) {
                                throw new RuntimeException("serviceMapping映射的地址不允许重复！");
                            }
                            ApiServiceMappingInfo info = new ApiServiceMappingInfo();

                            Object bean = springContextUtils.getBean(clazz);

                            info.setServiceInstance(bean);
                            info.setParamClass(m.getParameterTypes());
                            info.setMethod(m);
                            info.setReturnClass(m.getReturnType());
                            ApiServiceMapping.requestMap.put(method, info);
                        }
                    }
                }
            }
        }
    }

}